package com.yjf.ljr.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;

import com.yjf.ljr.common.CommonData;

public class ImageLoader {

	private HashMap<String, SoftReference<Bitmap>> mImageCache = new HashMap<String, SoftReference<Bitmap>>();
	
	private String mPath = ""; // 文件存储路径

	public ImageLoader() {
		if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState())) {
			mPath = CommonData.IMAMGE_DIR_SD + "/";
		} else {
			mPath = CommonData.IMAMGE_DIR_RAM + "/";
		}
	}
	
	public String getFilePath(){
		return mPath;
	}

	public Bitmap loadBitmap(final String imageUrl, final String imgTag, final ImageCallback imageCallback) {

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message message) {
				if (imageCallback != null) {
					imageCallback.imageLoader((Bitmap) message.obj, imageUrl);
				}
			}
		};

		// 读图片
		String name = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
		String path = "";
		// if (name.indexOf(".") > -1) {
		// name = name.substring(0, name.indexOf("."));
		// name = name + "_" +imgTag + ".jpg";
		// }
		if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState())) {
			path = CommonData.IMAMGE_DIR_SD + "/";
		} else {
			path = CommonData.IMAMGE_DIR_RAM + "/";
		}

		File f = new File(path + name);

		if (f.exists()) {
			Bitmap bitmap = null;
			if (mImageCache.containsKey(path + name + imgTag)) {

				SoftReference<Bitmap> softReference = mImageCache.get(path + name + imgTag);

				Bitmap bm = softReference.get();

				if (null != bm){
					return bm;
				}
			}

			try {
				BitmapFactory.Options opts = new BitmapFactory.Options();
				opts.inJustDecodeBounds = true;
				BitmapFactory.decodeFile(path + name, opts); // 获取Options的值

				opts.inSampleSize = computeInitialSampleSize(opts, -1, 720 * 1280);
				// 这里必然要将其设置回false,因为之前我们将其设置成了true
				opts.inJustDecodeBounds = false;

				bitmap = BitmapFactory.decodeFile(path + name, opts);
			} catch (OutOfMemoryError e) {
				if (bitmap != null) {
					bitmap.recycle();
				}
				e.printStackTrace();
			}

			mImageCache.put(path + name + imgTag, new SoftReference<Bitmap>(bitmap));
			return bitmap;
		} else {
			new Thread() {
				@Override
				public void run() {
					InputStream is = null;
					try {
						// Bitmap bitmap = getBitmap(imageUrl);

						URL u = null;
						u = new URL(imageUrl);
						Bitmap bitmap = null;
						byte[] data = null;

						// HttpURLConnection conn = (HttpURLConnection)
						// u.openConnection();
						// conn.setDoInput(true);
						// conn.setReadTimeout(30000);
						// conn.setConnectTimeout(15000);
						// conn.connect();
						// InputStream is = conn.getInputStream();
						// // bitmap = BitmapFactory.decodeStream(is);

						HttpClient client = new DefaultHttpClient();
						HttpUriRequest request = new HttpGet(imageUrl);
						HttpResponse response = client.execute(request);
//						int responseCode = response.getStatusLine().getStatusCode();
						// if(response.getStatusLine().getStatusCode() !=
						// HttpStatus.SC_OK) {
						//
						// }
						BufferedHttpEntity entity = new BufferedHttpEntity(response.getEntity());
						is = entity.getContent();						
//						String type = entity.getContentType() != null ?entity.getContentType().getValue():null;
						if (is == null) {
							System.out.println("stream is null");
							throw new RuntimeException("stream is null");
						} /*else if (null == type || !type.contains("image")) {
							System.out.println("is not image");
							throw new RuntimeException("is not image");
						}*/ else {
							try {
								data = readStream(is);
								if (data != null) {
									bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
								}
							} catch (OutOfMemoryError e) {
								if (bitmap != null) {
									bitmap.recycle();
								}
								is.close();
								e.printStackTrace();
							}
						}
						// if (!isImage(data)) {
						// System.out.println("stream is null");
						// throw new RuntimeException("stream is null");
						// }

						// 存图片
						if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
							String name = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
							String path = "";
							if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState())) {
								path = CommonData.IMAMGE_DIR_SD + "/";
							} else {
								path = CommonData.IMAMGE_DIR_RAM + "/";
							}
							// if (name.indexOf(".") > -1) {
							// name = name.substring(0, name.indexOf("."));
							// name = name + "_" +imgTag + ".jpg";
							// }
							File dir = new File(path);
							File file = new File(path + name);
							try {
								Runtime.getRuntime().exec("chmod 705 " + dir.getPath());
								Runtime.getRuntime().exec("chmod 604 " + file.getPath());
							} catch (Exception e) {
								e.printStackTrace();
							}
							if (!dir.exists()) {
								dir.mkdirs();
							}

							FileOutputStream outStream = new FileOutputStream(file);
							// bitmap.compress(Bitmap.CompressFormat.JPEG,
							// 100, outStream);
							outStream.write(data);
							outStream.close();
							is.close();

							mImageCache.put(path + name + imgTag, new SoftReference<Bitmap>(bitmap));
						}

						Message message = handler.obtainMessage(0, bitmap);
						handler.sendMessage(message);
					} catch (Exception e) {
						if (is != null) {
							try {
								is.close();
							} catch (IOException e1) {
								e1.printStackTrace();
							}
						}
						e.printStackTrace();
					}
				}
			}.start();
			return null;
		}
	}

	public void releaseImage(String imageUrl, String imgTag) {

		String name = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
		// if (name.indexOf(".") > -1) {
		// name = name.substring(0, name.indexOf("."));
		// name = name + "_" +imgTag + ".jpg";
		// }
		String path = CommonData.IMAMGE_DIR_SD + "/";

		if (mImageCache.containsKey(path + name + imgTag)) {

			SoftReference<Bitmap> reference = mImageCache.get(path + name + imgTag);

			Bitmap bitmap = reference.get();

			if (null != bitmap) {
				bitmap.recycle();
			}

			mImageCache.remove(path + name + imgTag);

		}

	}

	public void releaseImageAll() {
		if (mImageCache.size() > 0) {
			for (String url : mImageCache.keySet()) {

				SoftReference<Bitmap> reference = mImageCache.get(url);

				Bitmap bitmap = reference.get();
				if (null != bitmap) {
					bitmap.recycle();
				}
			}
			mImageCache.clear();
		}
	}

	// private static Bitmap getBitmap(String imageUrl) {
	// URL u = null;
	// Bitmap bitmap = null;
	// try {
	// u = new URL(imageUrl);
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// try {
	// HttpURLConnection conn = (HttpURLConnection) u.openConnection();
	// conn.setDoInput(true);
	// conn.setReadTimeout(30000);
	// conn.setConnectTimeout(15000);
	// conn.connect();
	// InputStream is = conn.getInputStream();
	// // bitmap = BitmapFactory.decodeStream(is);
	// if (is == null){
	// throw new RuntimeException("stream is null");
	// }else{
	// try {
	// byte[] data=readStream(is);
	// if(data != null){
	// bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
	// }
	// } catch (OutOfMemoryError e) {
	// e.printStackTrace();
	// }
	//
	// is.close();
	// }
	//
	// // is.close();
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	//
	// // int bitmapWidth = bitmap.getWidth();
	// // int bitmapHeight = bitmap.getHeight();
	// //// int newWidth = 180;
	// //// int newHeight = 180;
	// //// float scaleWidth = ((float) newWidth / bitmapWidth);
	// //// float scaleHeight = ((float) newHeight / bitmapHeight);
	// // Matrix matrix = new Matrix();
	// //// matrix.postScale(scaleWidth, scaleHeight);
	// // Bitmap reBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmapWidth,
	// // bitmapHeight, matrix, true);
	// //
	// // return reBitmap;
	// return bitmap;
	// }

	public static boolean isImage(byte[] b) {
		if (b == null || b.length < 10) {
			return false;
		}
		byte b0 = b[0];
		byte b1 = b[1];
		byte b2 = b[2];
		byte b3 = b[3];
		byte b6 = b[6];
		byte b7 = b[7];
		byte b8 = b[8];
		byte b9 = b[9];
		if (b0 == (byte) 'G' && b1 == (byte) 'I' && b2 == (byte) 'F') {
			return true;
		} else if (b1 == (byte) 'P' && b2 == (byte) 'N' && b3 == (byte) 'G') {
			return true;
		} else if (b6 == (byte) 'J' && b7 == (byte) 'F' && b8 == (byte) 'I' && b9 == (byte) 'F') {
			return true;
		} else {
			return false;
		}
	}

	/*
	 * 得到图片字节流 数组大小
	 */
	public static byte[] readStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		outStream.close();
		inStream.close();
		return outStream.toByteArray();
	}

	public interface ImageCallback {
		public void imageLoader(Bitmap bitmap, String imageUrl);
	}

	private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
		double w = options.outWidth;
		double h = options.outHeight;

		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.floor(Math.sqrt(w * h / maxNumOfPixels));
		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength),
				Math.floor(h / minSideLength));

		if (upperBound < lowerBound) {
			return lowerBound;
		}

		if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
			return 1;
		} else if (minSideLength == -1) {
			return lowerBound;
		} else {
			return upperBound;
		}
	}
}

